import 'dart:async';

import '../utils/ignorable_change_notifier.dart';

import '../cut_canvas.dart';

typedef IgnorableListener = void Function();

/// 双击时触发的缩放状态变更，在设定好的循环周期内触发对应状态
///
/// controller和通用controller模型一样，都需要在不需要使用时，调用[CutCanvasScaleStateController.dispose]方法
///
/// 使用[scaleStateStream]来监听状态变更
///
class CutCanvasScaleStateController {
  IgnorableValueNotifier<CanvasScaleState> _scaleStateNotifier;

  StreamController<CanvasScaleState> _scaleStateController =
      StreamController<CanvasScaleState>.broadcast();

  Stream<CanvasScaleState> get scaleStateStream => _scaleStateController.stream;

  CanvasScaleState prevScaleState;

  CanvasScaleState get scaleState => _scaleStateNotifier.value;

  CutCanvasScaleStateController() {
    _scaleStateNotifier = IgnorableValueNotifier(CanvasScaleState.initial);
    _scaleStateNotifier.addListener(_scaleStateChangeListener);

    _scaleStateController.sink.add(CanvasScaleState.initial);
    prevScaleState = CanvasScaleState.initial;
  }

  set scaleState(CanvasScaleState newValue) {
    if (_scaleStateNotifier.value == newValue) {
      return;
    }
    prevScaleState = _scaleStateNotifier.value;
    _scaleStateNotifier.value = newValue;
  }

  bool get hasChanged => prevScaleState != scaleState;

  bool get isZooming =>
      scaleState == CanvasScaleState.zoomedIn ||
      scaleState == CanvasScaleState.zoomedOut;

  void reset() {
    prevScaleState = scaleState;
    scaleState = CanvasScaleState.initial;
  }

  void dispose() {
    _scaleStateController.close();
    _scaleStateNotifier.dispose();
  }

  /// Nevermind this method :D, look away
  /// Seriously: It is used to change scale state without trigging updates on the []
  void setInvisibly(CanvasScaleState newValue) {
    if (_scaleStateNotifier.value == newValue) {
      return;
    }
    prevScaleState = _scaleStateNotifier.value;
    _scaleStateNotifier.updateIgnoring(newValue);
  }

  void _scaleStateChangeListener() {
    _scaleStateController.sink.add(scaleState);
  }

  /// 供内部使用，监听状态变更使用[outputScaleStateStream]即可
  void addIgnorableListener(IgnorableListener callback) {
    _scaleStateNotifier.addIgnorableListener(callback);
  }

  /// 供内部使用，监听状态变更使用[outputScaleStateStream]即可
  void removeIgnorableListener(IgnorableListener callback) {
    _scaleStateNotifier.removeIgnorableListener(callback);
  }
}
